home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / awksrc.zip / EVAL.C < prev    next >
C/C++ Source or Header  |  1993-09-27  |  32KB  |  1,223 lines

  1. /*
  2.  * eval.c - gawk parse tree interpreter 
  3.  */
  4.  
  5. /* 
  6.  * Copyright (C) 1986, 1988, 1989, 1991, 1992 the Free Software Foundation, Inc.
  7.  * 
  8.  * This file is part of GAWK, the GNU implementation of the
  9.  * AWK Progamming Language.
  10.  * 
  11.  * GAWK is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  * 
  16.  * GAWK is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  * 
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with GAWK; see the file COPYING.  If not, write to
  23.  * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  24.  */
  25.  
  26. #include "awk.h"
  27.  
  28. extern double pow P((double x, double y));
  29. extern double modf P((double x, double *yp));
  30. extern double fmod P((double x, double y));
  31.  
  32. static int eval_condition P((NODE *tree));
  33. static NODE *op_assign P((NODE *tree));
  34. static NODE *func_call P((NODE *name, NODE *arg_list));
  35. static NODE *match_op P((NODE *tree));
  36.  
  37. NODE *_t;        /* used as a temporary in macros */
  38. #ifdef MSDOS
  39. double _msc51bug;    /* to get around a bug in MSC 5.1 */
  40. #endif
  41. NODE *ret_node;
  42. int OFSlen;
  43. int ORSlen;
  44. int OFMTidx;
  45. int CONVFMTidx;
  46.  
  47. /* Macros and variables to save and restore function and loop bindings */
  48. /*
  49.  * the val variable allows return/continue/break-out-of-context to be
  50.  * caught and diagnosed
  51.  */
  52. #define PUSH_BINDING(stack, x, val) (memcpy ((char *)(stack), (char *)(x), sizeof (jmp_buf)), val++)
  53. #define RESTORE_BINDING(stack, x, val) (memcpy ((char *)(x), (char *)(stack), sizeof (jmp_buf)), val--)
  54.  
  55. static jmp_buf loop_tag;    /* always the current binding */
  56. static int loop_tag_valid = 0;    /* nonzero when loop_tag valid */
  57. static int func_tag_valid = 0;
  58. static jmp_buf func_tag;
  59. extern int exiting, exit_val;
  60.  
  61. /*
  62.  * This table is used by the regexp routines to do case independant
  63.  * matching. Basically, every ascii character maps to itself, except
  64.  * uppercase letters map to lower case ones. This table has 256
  65.  * entries, which may be overkill. Note also that if the system this
  66.  * is compiled on doesn't use 7-bit ascii, casetable[] should not be
  67.  * defined to the linker, so gawk should not load.
  68.  *
  69.  * Do NOT make this array static, it is used in several spots, not
  70.  * just in this file.
  71.  */
  72. #if 'a' == 97    /* it's ascii */
  73. char casetable[] = {
  74.     '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
  75.     '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
  76.     '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
  77.     '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
  78.     /* ' '     '!'     '"'     '#'     '$'     '%'     '&'     ''' */
  79.     '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
  80.     /* '('     ')'     '*'     '+'     ','     '-'     '.'     '/' */
  81.     '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
  82.     /* '0'     '1'     '2'     '3'     '4'     '5'     '6'     '7' */
  83.     '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
  84.     /* '8'     '9'     ':'     ';'     '<'     '='     '>'     '?' */
  85.     '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
  86.     /* '@'     'A'     'B'     'C'     'D'     'E'     'F'     'G' */
  87.     '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  88.     /* 'H'     'I'     'J'     'K'     'L'     'M'     'N'     'O' */
  89.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  90.     /* 'P'     'Q'     'R'     'S'     'T'     'U'     'V'     'W' */
  91.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  92.     /* 'X'     'Y'     'Z'     '['     '\'     ']'     '^'     '_' */
  93.     '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
  94.     /* '`'     'a'     'b'     'c'     'd'     'e'     'f'     'g' */
  95.     '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
  96.     /* 'h'     'i'     'j'     'k'     'l'     'm'     'n'     'o' */
  97.     '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
  98.     /* 'p'     'q'     'r'     's'     't'     'u'     'v'     'w' */
  99.     '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
  100.     /* 'x'     'y'     'z'     '{'     '|'     '}'     '~' */
  101.     '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
  102.     '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
  103.     '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
  104.     '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
  105.     '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
  106.     '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
  107.     '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
  108.     '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
  109.     '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
  110.     '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
  111.     '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
  112.     '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
  113.     '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
  114.     '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
  115.     '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
  116.     '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
  117.     '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
  118. };
  119. #else
  120. #include "You lose. You will need a translation table for your character set."
  121. #endif
  122.  
  123. /*
  124.  * Tree is a bunch of rules to run. Returns zero if it hit an exit()
  125.  * statement 
  126.  */
  127. int
  128. interpret(tree)
  129. register NODE *volatile tree;
  130. {
  131.     jmp_buf volatile loop_tag_stack; /* shallow binding stack for loop_tag */
  132.     static jmp_buf rule_tag; /* tag the rule currently being run, for NEXT
  133.                   * and EXIT statements.  It is static because
  134.                   * there are no nested rules */
  135.     register NODE *volatile t = NULL;    /* temporary */
  136.     NODE **volatile lhs;    /* lhs == Left Hand Side for assigns, etc */
  137.     NODE *volatile stable_tree;
  138.     int volatile traverse = 1;    /* True => loop thru tree (Node_rule_list) */
  139.  
  140.     if (tree == NULL)
  141.         return 1;
  142.     sourceline = tree->source_line;
  143.     source = tree->source_file;
  144.     switch (tree->type) {
  145.     case Node_rule_node:
  146.         traverse = 0;   /* False => one for-loop iteration only */
  147.         /* FALL THROUGH */
  148.     case Node_rule_list:
  149.         for (t = tree; t != NULL; t = t->rnode) {
  150.             if (traverse)
  151.                 tree = t->lnode;
  152.             sourceline = tree->source_line;
  153.             source = tree->source_file;
  154.             switch (setjmp(rule_tag)) {
  155.             case 0:    /* normal non-jump */
  156.                 /* test pattern, if any */
  157.                 if (tree->lnode == NULL ||
  158.                     eval_condition(tree->lnode))
  159.                     (void) interpret(tree->rnode);
  160.                 break;
  161.             case TAG_CONTINUE:    /* NEXT statement */
  162.                 return 1;
  163.             case TAG_BREAK:
  164.                 return 0;
  165.             default:
  166.                 cant_happen();
  167.             }
  168.             if (!traverse)          /* case Node_rule_node */
  169.                 break;          /* don't loop */
  170.         }
  171.         break;
  172.  
  173.     case Node_statement_list:
  174.         for (t = tree; t != NULL; t = t->rnode)
  175.             (void) interpret(t->lnode);
  176.         break;
  177.  
  178.     case Node_K_if:
  179.         if (eval_condition(tree->lnode)) {
  180.             (void) interpret(tree->rnode->lnode);
  181.         } else {
  182.             (void) interpret(tree->rnode->rnode);
  183.         }
  184.         break;
  185.  
  186.     case Node_K_while:
  187.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  188.  
  189.         stable_tree = tree;
  190.         while (eval_condition(stable_tree->lnode)) {
  191.             switch (setjmp(loop_tag)) {
  192.             case 0:    /* normal non-jump */
  193.                 (void) interpret(stable_tree->rnode);
  194.                 break;
  195.             case TAG_CONTINUE:    /* continue statement */
  196.                 break;
  197.             case TAG_BREAK:    /* break statement */
  198.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  199.                 return 1;
  200.             default:
  201.                 cant_happen();
  202.             }
  203.         }
  204.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  205.         break;
  206.  
  207.     case Node_K_do:
  208.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  209.         stable_tree = tree;
  210.         do {
  211.             switch (setjmp(loop_tag)) {
  212.             case 0:    /* normal non-jump */
  213.                 (void) interpret(stable_tree->rnode);
  214.                 break;
  215.             case TAG_CONTINUE:    /* continue statement */
  216.                 break;
  217.             case TAG_BREAK:    /* break statement */
  218.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  219.                 return 1;
  220.             default:
  221.                 cant_happen();
  222.             }
  223.         } while (eval_condition(stable_tree->lnode));
  224.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  225.         break;
  226.  
  227.     case Node_K_for:
  228.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  229.         (void) interpret(tree->forloop->init);
  230.         stable_tree = tree;
  231.         while (eval_condition(stable_tree->forloop->cond)) {
  232.             switch (setjmp(loop_tag)) {
  233.             case 0:    /* normal non-jump */
  234.                 (void) interpret(stable_tree->lnode);
  235.                 /* fall through */
  236.             case TAG_CONTINUE:    /* continue statement */
  237.                 (void) interpret(stable_tree->forloop->incr);
  238.                 break;
  239.             case TAG_BREAK:    /* break statement */
  240.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  241.                 return 1;
  242.             default:
  243.                 cant_happen();
  244.             }
  245.         }
  246.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  247.         break;
  248.  
  249.     case Node_K_arrayfor:
  250.         {
  251.         volatile struct search l;    /* For array_for */
  252.         Func_ptr after_assign = NULL;
  253.  
  254. #define hakvar forloop->init
  255. #define arrvar forloop->incr
  256.         PUSH_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  257.         lhs = get_lhs(tree->hakvar, &after_assign);
  258.         t = tree->arrvar;
  259.         if (t->type == Node_param_list)
  260.             t = stack_ptr[t->param_cnt];
  261.         stable_tree = tree;
  262.         for (assoc_scan(t, (struct search *)&l);
  263.              l.retval;
  264.              assoc_next((struct search *)&l)) {
  265.             unref(*((NODE **) lhs));
  266.             *lhs = dupnode(l.retval);
  267.             if (after_assign)
  268.                 (*after_assign)();
  269.             switch (setjmp(loop_tag)) {
  270.             case 0:
  271.                 (void) interpret(stable_tree->lnode);
  272.             case TAG_CONTINUE:
  273.                 break;
  274.  
  275.             case TAG_BREAK:
  276.                 RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  277.                 return 1;
  278.             default:
  279.                 cant_happen();
  280.             }
  281.         }
  282.         RESTORE_BINDING(loop_tag_stack, loop_tag, loop_tag_valid);
  283.         break;
  284.         }
  285.  
  286.     case Node_K_break:
  287.         if (loop_tag_valid == 0)
  288.             fatal("unexpected break");
  289.         longjmp(loop_tag, TAG_BREAK);
  290.         break;
  291.  
  292.     case Node_K_continue:
  293.         if (loop_tag_valid == 0) {
  294.             /*
  295.              * AT&T nawk treats continue outside of loops like
  296.              * next.  Allow it if not posix, and complain if
  297.              * lint.
  298.              */
  299.             static int warned = 0;
  300.  
  301.             if (do_lint && ! warned) {
  302.                 warning("use of `continue' outside of loop is not portable");
  303.                 warned = 1;
  304.             }
  305.             if (do_posix)
  306.                 fatal("use of `continue' outside of loop is not allowed");
  307.             longjmp(rule_tag, TAG_CONTINUE);
  308.         } else
  309.             longjmp(loop_tag, TAG_CONTINUE);
  310.         break;
  311.  
  312.     case Node_K_print:
  313.         do_print(tree);
  314.         break;
  315.  
  316.     case Node_K_printf:
  317.         do_printf(tree);
  318.         break;
  319.  
  320.     case Node_K_delete:
  321.         do_delete(tree->lnode, tree->rnode);
  322.         break;
  323.  
  324.     case Node_K_next:
  325.         longjmp(rule_tag, TAG_CONTINUE);
  326.         break;
  327.  
  328.     case Node_K_nextfile:
  329.         do_nextfile();
  330.         break;
  331.  
  332.     case Node_K_exit:
  333.         /*
  334.          * In A,K,&W, p. 49, it says that an exit statement "...
  335.          * causes the program to behave as if the end of input had
  336.          * occurred; no more input is read, and the END actions, if
  337.          * any are executed." This implies that the rest of the rules
  338.          * are not done. So we immediately break out of the main loop.
  339.          */
  340.         exiting = 1;
  341.         if (tree) {
  342.             t = tree_eval(tree->lnode);
  343.             exit_val = (int) force_number(t);
  344.         }
  345.         free_temp(t);
  346.         longjmp(rule_tag, TAG_BREAK);
  347.         break;
  348.  
  349.     case Node_K_return:
  350.         t = tree_eval(tree->lnode);
  351.         ret_node = dupnode(t);
  352.         free_temp(t);
  353.         longjmp(func_tag, TAG_RETURN);
  354.         break;
  355.  
  356.     default:
  357.         /*
  358.          * Appears to be an expression statement.  Throw away the
  359.          * value. 
  360.          */
  361.         if (do_lint && tree->type == Node_var)
  362.             warning("statement has no effect");
  363.         t = tree_eval(tree);
  364.         free_temp(t);
  365.         break;
  366.     }
  367.     return 1;
  368. }
  369.  
  370. /* evaluate a subtree */
  371.  
  372. NODE *
  373. r_tree_eval(tree)
  374. register NODE *tree;
  375. {
  376.     register NODE *r, *t1, *t2;    /* return value & temporary subtrees */
  377.     register NODE **lhs;
  378.     register int di;
  379.     AWKNUM x, x1, x2;
  380.     long lx;
  381. #ifdef CRAY
  382.     long lx2;
  383. #endif
  384.  
  385. #ifdef DEBUG
  386.     if (tree == NULL)
  387.         return Nnull_string;
  388.     if (tree->type == Node_val) {
  389.         if (tree->stref <= 0) cant_happen();
  390.         return tree;
  391.     }
  392.     if (tree->type == Node_var) {
  393.         if (tree->var_value->stref <= 0) cant_happen();
  394.         return tree->var_value;
  395.     }
  396.     if (tree->type == Node_param_list)
  397. /*        return (stack_ptr[(_t)->param_cnt])->var_value;  */
  398.         return (stack_ptr[(tree)->param_cnt])->var_value;
  399. #endif
  400.     switch (tree->type) {
  401.     case Node_and:
  402.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  403.                         && eval_condition(tree->rnode)));
  404.  
  405.     case Node_or:
  406.         return tmp_number((AWKNUM) (eval_condition(tree->lnode)
  407.                         || eval_condition(tree->rnode)));
  408.  
  409.     case Node_not:
  410.         return tmp_number((AWKNUM) ! eval_condition(tree->lnode));
  411.  
  412.         /* Builtins */
  413.     case Node_builtin:
  414.         return ((*tree->proc) (tree->subnode));
  415.  
  416.     case Node_K_getline:
  417.         return (do_getline(tree));
  418.  
  419.     case Node_in_array:
  420.         return tmp_number((AWKNUM) in_array(tree->lnode, tree->rnode));
  421.  
  422.     case Node_func_call:
  423.         return func_call(tree->rnode, tree->lnode);
  424.  
  425.         /* unary operations */
  426.     case Node_NR:
  427.     case Node_FNR:
  428.     case Node_NF:
  429.     case Node_FIELDWIDTHS:
  430.     case Node_FS:
  431.     case Node_RS:
  432.     case Node_field_spec:
  433.     case Node_subscript:
  434.     case Node_IGNORECASE:
  435.     case Node_OFS:
  436.     case Node_ORS:
  437.     case Node_OFMT:
  438.     case Node_CONVFMT:
  439.         lhs = get_lhs(tree, (Func_ptr *)0);
  440.         return *lhs;
  441.  
  442.     case Node_var_array:
  443.         fatal("attempt to use an array in a scalar context");
  444.  
  445.     case Node_unary_minus:
  446.         t1 = tree_eval(tree->subnode);
  447.         x = -force_number(t1);
  448.         free_temp(t1);
  449.         return tmp_number(x);
  450.  
  451.     case Node_cond_exp:
  452.         if (eval_condition(tree->lnode))
  453.             return tree_eval(tree->rnode->lnode);
  454.         return tree_eval(tree->rnode->rnode);
  455.  
  456.     case Node_match:
  457.     case Node_nomatch:
  458.     case Node_regex:
  459.         return match_op(tree);
  460.  
  461.     case Node_func:
  462.         fatal("function `%s' called with space between name and (,\n%s",
  463.             tree->lnode->param,
  464.             "or used in other expression context");
  465.  
  466.         /* assignments */
  467.     case Node_assign:
  468.         {
  469.         Func_ptr after_assign = NULL;
  470.  
  471.         r = tree_eval(tree->rnode);
  472.         lhs = get_lhs(tree->lnode, &after_assign);
  473.         if (r != *lhs) {
  474.             NODE *save;
  475.  
  476.             save = *lhs;
  477.             *lhs = dupnode(r);
  478.             unref(save);
  479.         }
  480.         free_temp(r);
  481.         if (after_assign)
  482.             (*after_assign)();
  483.         return *lhs;
  484.         }
  485.  
  486.     case Node_concat:
  487.         {
  488. #define    STACKSIZE    10
  489.         NODE *stack[STACKSIZE];
  490.         register NODE **sp;
  491.         register int len;
  492.         char *str;
  493.         register char *dest;
  494.  
  495.         sp = stack;
  496.         len = 0;
  497.         while (tree->type == Node_concat) {
  498.             *sp = force_string(tree_eval(tree->lnode));
  499.             tree = tree->rnode;
  500.             len += (*sp)->stlen;
  501.             if (++sp == &stack[STACKSIZE-2]) /* one more and NULL */
  502.                 break;
  503.         }
  504.         *sp = force_string(tree_eval(tree));
  505.         len += (*sp)->stlen;
  506.         *++sp = NULL;
  507.         emalloc(str, char *, len+2, "tree_eval");
  508.         dest = str;
  509.         sp = stack;
  510.         while (*sp) {
  511.             memcpy(dest, (*sp)->stptr, (*sp)->stlen);
  512.             dest += (*sp)->stlen;
  513.             free_temp(*sp);
  514.             sp++;
  515.         }
  516.         r = make_str_node(str, len, ALREADY_MALLOCED);
  517.         r->flags |= TEMP;
  518.         }
  519.         return r;
  520.  
  521.     /* other assignment types are easier because they are numeric */
  522.     case Node_preincrement:
  523.     case Node_predecrement:
  524.     case Node_postincrement:
  525.     case Node_postdecrement:
  526.     case Node_assign_exp:
  527.     case Node_assign_times:
  528.     case Node_assign_quotient:
  529.     case Node_assign_mod:
  530.     case Node_assign_plus:
  531.     case Node_assign_minus:
  532.         return op_assign(tree);
  533.     default:
  534.         break;    /* handled below */
  535.     }
  536.  
  537.     /* evaluate subtrees in order to do binary operation, then keep going */
  538.     t1 = tree_eval(tree->lnode);
  539.     t2 = tree_eval(tree->rnode);
  540.  
  541.     switch (tree->type) {
  542.     case Node_geq:
  543.     case Node_leq:
  544.     case Node_greater:
  545.     case Node_less:
  546.     case Node_notequal:
  547.     case Node_equal:
  548.         di = cmp_nodes(t1, t2);
  549.         free_temp(t1);
  550.         free_temp(t2);
  551.         switch (tree->type) {
  552.         case Node_equal:
  553.             return tmp_number((AWKNUM) (di == 0));
  554.         case Node_notequal:
  555.             return tmp_number((AWKNUM) (di != 0));
  556.         case Node_less:
  557.             return tmp_number((AWKNUM) (di < 0));
  558.         case Node_greater:
  559.             return tmp_number((AWKNUM) (di > 0));
  560.         case Node_leq:
  561.             return tmp_number((AWKNUM) (di <= 0));
  562.         case Node_geq:
  563.             return tmp_number((AWKNUM) (di >= 0));
  564.         default:
  565.             cant_happen();
  566.         }
  567.         break;
  568.     default:
  569.         break;    /* handled below */
  570.     }
  571.  
  572.     x1 = force_number(t1);
  573.     free_temp(t1);
  574.     x2 = force_number(t2);
  575.     free_temp(t2);
  576.     switch (tree->type) {
  577.     case Node_exp:
  578.         if ((lx = (long) x2) == x2 && lx >= 0) {    /* integer exponent */
  579.             if (lx == 0)
  580.                 x = 1;
  581.             else if (lx == 1)
  582.                 x = x1;
  583.             else {
  584.                 /* doing it this way should be more precise */
  585.                 for (x = x1; --lx; )
  586.                     x *= x1;
  587.             }
  588.         } else
  589.             x = pow((double) x1, (double) x2);
  590.         return tmp_number(x);
  591.  
  592.     case Node_times:
  593.         return tmp_number(x1 * x2);
  594.  
  595.     case Node_quotient:
  596.         if (x2 == 0)
  597.             fatal("division by zero attempted");
  598. #ifdef _CRAY
  599.         /*
  600.          * special case for integer division, put in for Cray
  601.          */
  602.         lx2 = x2;
  603.         if (lx2 == 0)
  604.             return tmp_number(x1 / x2);
  605.         lx = (long) x1 / lx2;
  606.         if (lx * x2 == x1)
  607.             return tmp_number((AWKNUM) lx);
  608.         else
  609. #endif
  610.             return tmp_number(x1 / x2);
  611.  
  612.     case Node_mod:
  613.         if (x2 == 0)
  614.             fatal("division by zero attempted in mod");
  615. #ifndef FMOD_MISSING
  616.         return tmp_number(fmod (x1, x2));
  617. #else
  618.         (void) modf(x1 / x2, &x);
  619.         return tmp_number(x1 - x * x2);
  620. #endif
  621.  
  622.     case Node_plus:
  623.         return tmp_number(x1 + x2);
  624.  
  625.     case Node_minus:
  626.         return tmp_number(x1 - x2);
  627.  
  628.     case Node_var_array:
  629.         fatal("attempt to use an array in a scalar context");
  630.  
  631.     default:
  632.         fatal("illegal type (%d) in tree_eval", tree->type);
  633.     }
  634.     return 0;
  635. }
  636.  
  637. /* Is TREE true or false?  Returns 0==false, non-zero==true */
  638. static int
  639. eval_condition(tree)
  640. register NODE *tree;
  641. {
  642.     register NODE *t1;
  643.     register int ret;
  644.  
  645.     if (tree == NULL)    /* Null trees are the easiest kinds */
  646.         return 1;
  647.     if (tree->type == Node_line_range) {
  648.         /*
  649.          * Node_line_range is kind of like Node_match, EXCEPT: the
  650.          * lnode field (more properly, the condpair field) is a node
  651.          * of a Node_cond_pair; whether we evaluate the lnode of that
  652.          * node or the rnode depends on the triggered word.  More
  653.          * precisely:  if we are not yet triggered, we tree_eval the
  654.          * lnode; if that returns true, we set the triggered word. 
  655.          * If we are triggered (not ELSE IF, note), we tree_eval the
  656.          * rnode, clear triggered if it succeeds, and perform our
  657.          * action (regardless of success or failure).  We want to be
  658.          * able to begin and end on a single input record, so this
  659.          * isn't an ELSE IF, as noted above.
  660.          */
  661.         if (!tree->triggered)
  662.             if (!eval_condition(tree->condpair->lnode))
  663.                 return 0;
  664.             else
  665.                 tree->triggered = 1;
  666.         /* Else we are triggered */
  667.         if (eval_condition(tree->condpair->rnode))
  668.             tree->triggered = 0;
  669.         return 1;
  670.     }
  671.  
  672.     /*
  673.      * Could just be J.random expression. in which case, null and 0 are
  674.      * false, anything else is true 
  675.      */
  676.  
  677.     t1 = tree_eval(tree);
  678.     if (t1->flags & MAYBE_NUM)
  679.         (void) force_number(t1);
  680.     if (t1->flags & NUMBER)
  681.         ret = t1->numbr != 0.0;
  682.     else
  683.         ret = t1->stlen != 0;
  684.     free_temp(t1);
  685.     return ret;
  686. }
  687.  
  688. /*
  689.  * compare two nodes, returning negative, 0, positive
  690.  */
  691. int
  692. cmp_nodes(t1, t2)
  693. register NODE *t1, *t2;
  694. {
  695.     register int ret;
  696.     register int len1, len2;
  697.  
  698.     if (t1 == t2)
  699.         return 0;
  700.     if (t1->flags & MAYBE_NUM)
  701.         (void) force_number(t1);
  702.     if (t2->flags & MAYBE_NUM)
  703.         (void) force_number(t2);
  704.     if ((t1->flags & NUMBER) && (t2->flags & NUMBER)) {
  705.         if (t1->numbr == t2->numbr) return 0;
  706.         else if (t1->numbr - t2->numbr < 0)  return -1;
  707.         else return 1;
  708.     }
  709.     (void) force_string(t1);
  710.     (void) force_string(t2);
  711.     len1 = t1->stlen;
  712.     len2 = t2->stlen;
  713.     if (len1 == 0 || len2 == 0)
  714.         return len1 - len2;
  715.     ret = memcmp(t1->stptr, t2->stptr, len1 <= len2 ? len1 : len2);
  716.     return ret == 0 ? len1-len2 : ret;
  717. }
  718.  
  719. static NODE *
  720. op_assign(tree)
  721. register NODE *tree;
  722. {
  723.     AWKNUM rval, lval;
  724.     NODE **lhs;
  725.     AWKNUM t1, t2;
  726.     long ltemp;
  727.     NODE *tmp;
  728.     Func_ptr after_assign = NULL;
  729.  
  730.     lhs = get_lhs(tree->lnode, &after_assign);
  731.     lval = force_number(*lhs);
  732.  
  733.     /*
  734.      * Can't unref *lhs until we know the type; doing so
  735.      * too early breaks   x += x   sorts of things.
  736.      */
  737.     switch(tree->type) {
  738.     case Node_preincrement:
  739.     case Node_predecrement:
  740.         unref(*lhs);
  741.         *lhs = make_number(lval +
  742.                    (tree->type == Node_preincrement ? 1.0 : -1.0));
  743.         if (after_assign)
  744.             (*after_assign)();
  745.         return *lhs;
  746.  
  747.     case Node_postincrement:
  748.     case Node_postdecrement:
  749.         unref(*lhs);
  750.         *lhs = make_number(lval +
  751.                    (tree->type == Node_postincrement ? 1.0 : -1.0));
  752.         if (after_assign)
  753.             (*after_assign)();
  754.         return tmp_number(lval);
  755.     default:
  756.         break;    /* handled below */
  757.     }
  758.  
  759.     tmp = tree_eval(tree->rnode);
  760.     rval = force_number(tmp);
  761.     free_temp(tmp);
  762.     unref(*lhs);
  763.     switch(tree->type) {
  764.     case Node_assign_exp:
  765.         if ((ltemp = (long) rval) == rval) {    /* integer exponent */
  766.             if (ltemp == 0)
  767.                 *lhs = make_number((AWKNUM) 1);
  768.             else if (ltemp == 1)
  769.                 *lhs = make_number(lval);
  770.             else {
  771.                 /* doing it this way should be more precise */
  772.                 for (t1 = t2 = lval; --ltemp; )
  773.                     t1 *= t2;
  774.                 *lhs = make_number(t1);
  775.             }
  776.         } else
  777.             *lhs = make_number((AWKNUM) pow((double) lval, (double) rval));
  778.         break;
  779.  
  780.     case Node_assign_times:
  781.         *lhs = make_number(lval * rval);
  782.         break;
  783.  
  784.     case Node_assign_quotient:
  785.         if (rval == (AWKNUM) 0)
  786.             fatal("division by zero attempted in /=");
  787. #ifdef _CRAY
  788.         /*
  789.          * special case for integer division, put in for Cray
  790.          */
  791.         ltemp = rval;
  792.         if (ltemp == 0) {
  793.             *lhs = make_number(lval / rval);
  794.             break;
  795.         }
  796.         ltemp = (long) lval / ltemp;
  797.         if (ltemp * lval == rval)
  798.             *lhs = make_number((AWKNUM) ltemp);
  799.         else
  800. #endif
  801.             *lhs = make_number(lval / rval);
  802.         break;
  803.  
  804.     case Node_assign_mod:
  805.         if (rval == (AWKNUM) 0)
  806.             fatal("division by zero attempted in %=");
  807. #ifndef FMOD_MISSING
  808.         *lhs = make_number(fmod(lval, rval));
  809. #else
  810.         (void) modf(lval / rval, &t1);
  811.         t2 = lval - rval * t1;
  812.         *lhs = make_number(t2);
  813. #endif
  814.         break;
  815.  
  816.     case Node_assign_plus:
  817.         *lhs = make_number(lval + rval);
  818.         break;
  819.  
  820.     case Node_assign_minus:
  821.         *lhs = make_number(lval - rval);
  822.         break;
  823.     default:
  824.         cant_happen();
  825.     }
  826.     if (after_assign)
  827.         (*after_assign)();
  828.     return *lhs;
  829. }
  830.  
  831. NODE **stack_ptr;
  832.  
  833. static NODE *
  834. func_call(name, arg_list)
  835. NODE *name;        /* name is a Node_val giving function name */
  836. NODE *arg_list;        /* Node_expression_list of calling args. */
  837. {
  838.     register NODE *arg, *argp, *r;
  839.     NODE *n, *f;
  840.     jmp_buf volatile func_tag_stack;
  841.     jmp_buf volatile loop_tag_stack;
  842.     int volatile save_loop_tag_valid = 0;
  843.     NODE **volatile save_stack, *save_ret_node;
  844.     NODE **volatile local_stack = NULL, **sp;
  845.     int count;
  846.     extern NODE *ret_node;
  847.  
  848.     /*
  849.      * retrieve function definition node
  850.      */
  851.     f = lookup(name->stptr);
  852.     if (!f || f->type != Node_func)
  853.         fatal("function `%s' not defined", name->stptr);
  854. #ifdef FUNC_TRACE
  855.     fprintf(stderr, "function %s called\n", name->stptr);
  856. #endif
  857.     count = f->lnode->param_cnt;
  858.     if (count)
  859.         emalloc(local_stack, NODE **, count*sizeof(NODE *), "func_call");
  860.     sp = local_stack;
  861.  
  862.     /*
  863.      * for each calling arg. add NODE * on stack
  864.      */
  865.     for (argp = arg_list; count && argp != NULL; argp = argp->rnode) {
  866.         arg = argp->lnode;
  867.         getnode(r);
  868.         r->type = Node_var;
  869.         /*
  870.          * call by reference for arrays; see below also
  871.          */
  872.         if (arg->type == Node_param_list)
  873.             arg = stack_ptr[arg->param_cnt];
  874.         if (arg->type == Node_var_array)
  875.             *r = *arg;
  876.         else {
  877.             n = tree_eval(arg);
  878.             r->lnode = dupnode(n);
  879.             r->rnode = (NODE *) NULL;
  880.             free_temp(n);
  881.           }
  882.         *sp++ = r;
  883.         count--;
  884.     }
  885.     if (argp != NULL)    /* left over calling args. */
  886.         warning(
  887.             "function `%s' called with more arguments than declared",
  888.             name->stptr);
  889.     /*
  890.      * add remaining params. on stack with null value
  891.      */
  892.     while (count-- > 0) {
  893.         getnode(r);
  894.         r->type = Node_var;
  895.         r->lnode = Nnull_string;
  896.         r->rnode = (NODE *) NULL;
  897.         *sp++ = r;
  898.     }
  899.  
  900.     /*
  901.      * Execute function body, saving context, as a return statement
  902.      * will longjmp back here.
  903.      *
  904.      * Have to save and restore the loop_tag stuff so that a return
  905.      * inside a loop in a function body doesn't scrog any loops going
  906.      * on in the main program.  We save the necessary info in variables
  907.      * local to this function so that function nesting works OK.
  908.      * We also only bother to save the loop stuff if we're in a loop
  909.      * when the function is called.
  910.      */
  911.     if (loop_tag_valid) {
  912.         int junk = 0;
  913.  
  914.         save_loop_tag_valid = (volatile int) loop_tag_valid;
  915.         PUSH_BINDING(loop_tag_stack, loop_tag, junk);
  916.         loop_tag_valid = 0;
  917.     }
  918.     save_stack = stack_ptr;
  919.     stack_ptr = local_stack;
  920.     PUSH_BINDING(func_tag_stack, func_tag, func_tag_valid);
  921.     save_ret_node = ret_node;
  922.     ret_node = Nnull_string;    /* default return value */
  923.     if (setjmp(func_tag) == 0)
  924.         (void) interpret(f->rnode);
  925.  
  926.     r = ret_node;
  927.     ret_node = (NODE *) save_ret_node;
  928.     RESTORE_BINDING(func_tag_stack, func_tag, func_tag_valid);
  929.     stack_ptr = (NODE **) save_stack;
  930.  
  931.     /*
  932.      * here, we pop each parameter and check whether
  933.      * it was an array.  If so, and if the arg. passed in was
  934.      * a simple variable, then the value should be copied back.
  935.      * This achieves "call-by-reference" for arrays.
  936.      */
  937.     sp = local_stack;
  938.     count = f->lnode->param_cnt;
  939.     for (argp = arg_list; count > 0 && argp != NULL; argp = argp->rnode) {
  940.         arg = argp->lnode;
  941.         if (arg->type == Node_param_list)
  942.             arg = stack_ptr[arg->param_cnt];
  943.         n = *sp++;
  944.         if (arg->type == Node_var && n->type == Node_var_array) {
  945.             /* should we free arg->var_value ? */
  946.             arg->var_array = n->var_array;
  947.             arg->type = Node_var_array;
  948.         }
  949.         unref(n->lnode);
  950.         freenode(n);
  951.         count--;
  952.     }
  953.     while (count-- > 0) {
  954.         n = *sp++;
  955.         /* if n is an (local) array, all the elements should be freed */
  956.         if (n->type == Node_var_array) {
  957.             assoc_clear(n);
  958.             free(n->var_array);
  959.         }
  960.         unref(n->lnode);
  961.         freenode(n);
  962.     }
  963.     if (local_stack)
  964.         free((char *) local_stack);
  965.  
  966.     /* Restore the loop_tag stuff if necessary. */
  967.     if (save_loop_tag_valid) {
  968.         int junk = 0;
  969.  
  970.         loop_tag_valid = (int) save_loop_tag_valid;
  971.         RESTORE_BINDING(loop_tag_stack, loop_tag, junk);
  972.     }
  973.  
  974.     if (!(r->flags & PERM))
  975.         r->flags |= TEMP;
  976.     return r;
  977. }
  978.  
  979. /*
  980.  * This returns a POINTER to a node pointer. get_lhs(ptr) is the current
  981.  * value of the var, or where to store the var's new value 
  982.  */
  983.  
  984. NODE **
  985. get_lhs(ptr, assign)
  986. register NODE *ptr;
  987. Func_ptr *assign;
  988. {
  989.     register NODE **aptr = NULL;
  990.     register NODE *n;
  991.  
  992.     switch (ptr->type) {
  993.     case Node_var_array:
  994.         fatal("attempt to use an array in a scalar context");
  995.     case Node_var:
  996.         aptr = &(ptr->var_value);
  997. #ifdef DEBUG
  998.         if (ptr->var_value->stref <= 0)
  999.             cant_happen();
  1000. #endif
  1001.         break;
  1002.  
  1003.     case Node_FIELDWIDTHS:
  1004.         aptr = &(FIELDWIDTHS_node->var_value);
  1005.         if (assign)
  1006.             *assign = set_FIELDWIDTHS;
  1007.         break;
  1008.  
  1009.     case Node_RS:
  1010.         aptr = &(RS_node->var_value);
  1011.         if (assign)
  1012.             *assign = set_RS;
  1013.         break;
  1014.  
  1015.     case Node_FS:
  1016.         aptr = &(FS_node->var_value);
  1017.         if (assign)
  1018.             *assign = set_FS;
  1019.         break;
  1020.  
  1021.     case Node_FNR:
  1022.         unref(FNR_node->var_value);
  1023.         FNR_node->var_value = make_number((AWKNUM) FNR);
  1024.         aptr = &(FNR_node->var_value);
  1025.         if (assign)
  1026.             *assign = set_FNR;
  1027.         break;
  1028.  
  1029.     case Node_NR:
  1030.         unref(NR_node->var_value);
  1031.         NR_node->var_value = make_number((AWKNUM) NR);
  1032.         aptr = &(NR_node->var_value);
  1033.         if (assign)
  1034.             *assign = set_NR;
  1035.         break;
  1036.  
  1037.     case Node_NF:
  1038.         if (NF == -1)
  1039.             (void) get_field(HUGE-1, assign); /* parse record */
  1040.         unref(NF_node->var_value);
  1041.         NF_node->var_value = make_number((AWKNUM) NF);
  1042.         aptr = &(NF_node->var_value);
  1043.         if (assign)
  1044.             *assign = set_NF;
  1045.         break;
  1046.  
  1047.     case Node_IGNORECASE:
  1048.         unref(IGNORECASE_node->var_value);
  1049.         IGNORECASE_node->var_value = make_number((AWKNUM) IGNORECASE);
  1050.         aptr = &(IGNORECASE_node->var_value);
  1051.         if (assign)
  1052.             *assign = set_IGNORECASE;
  1053.         break;
  1054.  
  1055.     case Node_OFMT:
  1056.         aptr = &(OFMT_node->var_value);
  1057.         if (assign)
  1058.             *assign = set_OFMT;
  1059.         break;
  1060.  
  1061.     case Node_CONVFMT:
  1062.         aptr = &(CONVFMT_node->var_value);
  1063.         if (assign)
  1064.             *assign = set_CONVFMT;
  1065.         break;
  1066.  
  1067.     case Node_ORS:
  1068.         aptr = &(ORS_node->var_value);
  1069.         if (assign)
  1070.             *assign = set_ORS;
  1071.         break;
  1072.  
  1073.     case Node_OFS:
  1074.         aptr = &(OFS_node->var_value);
  1075.         if (assign)
  1076.             *assign = set_OFS;
  1077.         break;
  1078.  
  1079.     case Node_param_list:
  1080.         aptr = &(stack_ptr[ptr->param_cnt]->var_value);
  1081.         break;
  1082.  
  1083.     case Node_field_spec:
  1084.         {
  1085.         int field_num;
  1086.  
  1087.         n = tree_eval(ptr->lnode);
  1088.         field_num = (int) force_number(n);
  1089.         free_temp(n);
  1090.         if (field_num < 0)
  1091.             fatal("attempt to access field %d", field_num);
  1092.         if (field_num == 0 && field0_valid) {    /* short circuit */
  1093.             aptr = &fields_arr[0];
  1094.             if (assign)
  1095.                 *assign = reset_record;
  1096.             break;
  1097.         }
  1098.         aptr = get_field(field_num, assign);
  1099.         break;
  1100.         }
  1101.     case Node_subscript:
  1102.         n = ptr->lnode;
  1103.         if (n->type == Node_param_list)
  1104.             n = stack_ptr[n->param_cnt];
  1105.         aptr = assoc_lookup(n, concat_exp(ptr->rnode));
  1106.         break;
  1107.  
  1108.     case Node_func:
  1109.         fatal ("`%s' is a function, assignment is not allowed",
  1110.             ptr->lnode->param);
  1111.     default:
  1112.         cant_happen();
  1113.     }
  1114.     return aptr;
  1115. }
  1116.  
  1117. static NODE *
  1118. match_op(tree)
  1119. register NODE *tree;
  1120. {
  1121.     register NODE *t1;
  1122.     register Regexp *rp;
  1123.     int i;
  1124.     int match = 1;
  1125.  
  1126.     if (tree->type == Node_nomatch)
  1127.         match = 0;
  1128.     if (tree->type == Node_regex)
  1129.         t1 = *get_field(0, (Func_ptr *) 0);
  1130.     else {
  1131.         t1 = force_string(tree_eval(tree->lnode));
  1132.         tree = tree->rnode;
  1133.     }
  1134.     rp = re_update(tree);
  1135.     i = research(rp, t1->stptr, 0, t1->stlen, 0);
  1136.     i = (i == -1) ^ (match == 1);
  1137.     free_temp(t1);
  1138.     return tmp_number((AWKNUM) i);
  1139. }
  1140.  
  1141. void
  1142. set_IGNORECASE()
  1143. {
  1144.     static int warned = 0;
  1145.  
  1146.     if ((do_lint || strict) && ! warned) {
  1147.         warned = 1;
  1148.         warning("IGNORECASE not supported in compatibility mode");
  1149.     }
  1150.     IGNORECASE = (force_number(IGNORECASE_node->var_value) != 0.0);
  1151.     set_FS();
  1152. }
  1153.  
  1154. void
  1155. set_OFS()
  1156. {
  1157.     OFS = force_string(OFS_node->var_value)->stptr;
  1158.     OFSlen = OFS_node->var_value->stlen;
  1159.     OFS[OFSlen] = '\0';
  1160. }
  1161.  
  1162. void
  1163. set_ORS()
  1164. {
  1165.     ORS = force_string(ORS_node->var_value)->stptr;
  1166.     ORSlen = ORS_node->var_value->stlen;
  1167.     ORS[ORSlen] = '\0';
  1168. }
  1169.  
  1170. static NODE **fmt_list = NULL;
  1171. static int fmt_ok P((NODE *n));
  1172. static int fmt_index P((NODE *n));
  1173.  
  1174. static int
  1175. fmt_ok(n)
  1176. NODE *n;
  1177. {
  1178.     /* to be done later */
  1179.     return 1;
  1180. }
  1181.  
  1182. static int
  1183. fmt_index(n)
  1184. NODE *n;
  1185. {
  1186.     register int ix = 0;
  1187.     static int fmt_num = 4;
  1188.     static int fmt_hiwater = 0;
  1189.  
  1190.     if (fmt_list == NULL)
  1191.         emalloc(fmt_list, NODE **, fmt_num*sizeof(*fmt_list), "fmt_index");
  1192.     (void) force_string(n);
  1193.     while (ix < fmt_hiwater) {
  1194.         if (cmp_nodes(fmt_list[ix], n) == 0)
  1195.             return ix;
  1196.         ix++;
  1197.     }
  1198.     /* not found */
  1199.     n->stptr[n->stlen] = '\0';
  1200.     if (!fmt_ok(n))
  1201.         warning("bad FMT specification");
  1202.     if (fmt_hiwater >= fmt_num) {
  1203.         fmt_num *= 2;
  1204.         emalloc(fmt_list, NODE **, fmt_num, "fmt_index");
  1205.     }
  1206.     fmt_list[fmt_hiwater] = dupnode(n);
  1207.     return fmt_hiwater++;
  1208. }
  1209.  
  1210. void
  1211. set_OFMT()
  1212. {
  1213.     OFMTidx = fmt_index(OFMT_node->var_value);
  1214.     OFMT = fmt_list[OFMTidx]->stptr;
  1215. }
  1216.  
  1217. void
  1218. set_CONVFMT()
  1219. {
  1220.     CONVFMTidx = fmt_index(CONVFMT_node->var_value);
  1221.     CONVFMT = fmt_list[CONVFMTidx]->stptr;
  1222. }
  1223.